const jwt = require('jsonwebtoken');
const helper = require('../../util/helper');
const config = require('../../config/environment/index');
const mysql = require('../../core/mysql');

const log = require('../../core/logger').getLogger("system");
const moment = require('moment');
const common = require('../../core/common');
const netMode = require('../../public/config/networkMode');
const stringUtils = require('../../core/util/StringUtils');
const _ = require('lodash');

/*
  request {
      model_id: 1,
 product_name:'红外感应器'，
 vendor：'鸿雁'，
  }
 */

// function insertProduct(ctx,newproduct, firstProperties,secondProperties,cotrolPropertylength,dicParent){
//   return
// };


exports.add = async(ctx) => {
  try {
      let product_name = ctx.request.body.product_name ? ctx.request.body.product_name.trim() : '' || '';
      let pic_url = ctx.request.body.pic_url || '';
      let vendor_id = ctx.request.body.vendor_id || 0;
      let model_type_id = ctx.request.body.model_type_id || 0;
      let protocol_id = ctx.request.body.protocol_id || 0;
      let model_name = ctx.request.body.model_name || '';
      let product_property = ctx.request.body.product_property ?
          (ctx.request.body.product_property.trim() !== '' ? JSON.parse(ctx.request.body.product_property) : [])
          : [];
      if (product_name === '' || pic_url === '' || parseInt(vendor_id) <= 0 || parseInt(model_type_id) <= 0
          || parseInt(protocol_id) <= 0 || model_name === '') {
          ctx.body = {
              result: 201,
              message: `请补全设备属性`
          };
          return;
      }
      let selectProduct = await mysql.query(`select * from product where product_name = ? and vendor_id = ? `, [product_name,vendor_id]);
      if (selectProduct.length > 0 ){
          ctx.body = {
              result: 201,
              message: "已存在此产品"
          };
          return
      }
      let model_type_name = '未知';
      let selectRows = await mysql.query(`SELECT * FROM model_type WHERE model_type_id = ?`, model_type_id);
      if (selectRows.length > 0){
          model_type_name = selectRows[0].model_type_name.endsWith('类') ?
              selectRows[0].model_type_name.substr(0,selectRows[0].model_type_name.length-1)
              : selectRows[0].model_type_name;
      }
      let firstProperties = [];
      let secondProperties = [];
      let dicControlId = {};
      let dicParent = {};
      let cotrolPropertylength = 0;
      for(let property of Object.values(product_property)){
          let match = property.property_name.match('_\\d+$');
          if (match && match.length > 0){
              if (!dicControlId[match[0]]) {
                  let newProperty = {};
                  newProperty.function = model_type_name + match[0];
                  newProperty.property_name = 'control'+ match[0];
                  newProperty.unit = '';
                  newProperty.range = '';
                  newProperty.value_description = '';
                  firstProperties.push(newProperty);
                  dicControlId[match[0]] = firstProperties.length;
              }
              secondProperties.push(property);
              dicParent[cotrolPropertylength++] = dicControlId[match[0]] - 1;
          }else{
              if (!dicControlId['_0'])  {
                  let newProperty = {};
                  newProperty.function = product_name;
                  newProperty.property_name = 'control_0';
                  newProperty.unit = '';
                  newProperty.range = '';
                  newProperty.value_description = '';
                  firstProperties.push(newProperty);
                  dicControlId['_0'] = firstProperties.length;
              }
              secondProperties.push(property);
              dicParent[cotrolPropertylength++] = dicControlId['_0'] - 1;
          }
      }

      let control_type = (cotrolPropertylength > 0) ? 1 : 0;
      let create_time = moment().format('YYYY-MM-DD HH:mm:ss');
      let update_time = moment().format('YYYY-MM-DD HH:mm:ss');
      let newproduct = {
          product_name,
          pic_url,
          vendor_id,
          model_type_id,
          protocol_id,
          model_name,
          control_type,
          create_time,
          update_time,
          is_deleted:0
      };
      await new Promise((resolve, reject) => {
          try {
              var trans = mysql.Client.startTransaction();
              trans.query(`INSERT INTO product SET ?`, newproduct, function(err, info) {
                  if(err || info.affectedRows === 0){
                      trans.rollback();
                      ctx.body = {
                          result: 203,
                          message: "新增设备失败"+ err.toString()
                      };
                      resolve(ctx);
                  } else{
                      if (firstProperties.length <= 0){
                          trans.commit();
                          ctx.body = {
                              result: 200,
                              id: info.insertId,
                              message: "新增设备成功"
                          };
                          resolve(ctx);
                          return;
                      }
                      let sqlInsertFirstProperty = `INSERT INTO product_property (function, property_name, product_id, unit, \`range\`, value_description) VALUES `;
                      firstProperties.forEach(ele => {
                          sqlInsertFirstProperty += `('${ele.function}', '${ele.property_name}', ${info.insertId}, '${ele.unit}', '${ele.range}', '${ele.value_description}'),`;
                      })
                      sqlInsertFirstProperty = sqlInsertFirstProperty.substr(0,sqlInsertFirstProperty.length-1);
                      trans.query(sqlInsertFirstProperty, function(err,insertFirstPropertyResult) {
                          if(err || insertFirstPropertyResult.affectedRows !== firstProperties.length){
                              trans.rollback();
                              ctx.body = {
                                  result: 204,
                                  message: "新增设备失败"+ err.toString()
                              };
                              resolve(ctx);
                          } else{
                              if (cotrolPropertylength <= 0){
                                  trans.commit();
                                  ctx.body = {
                                      result: 200,
                                      id: info.insertId,
                                      message: "新增设备成功"
                                  };
                                  resolve(ctx);
                              } else{
                                  let dicControlPropertyID = {};
                                  for (i = 0; i < cotrolPropertylength; i++){
                                      dicControlPropertyID[i] = insertFirstPropertyResult.insertId + i;
                                  }
                                  let sqlInsertSecondProperty = `INSERT INTO product_property (function, property_name, parent_property_id, product_id, unit, \`range\`, value_description) VALUES `;
                                  for (i = 0;i < secondProperties.length; i++){
                                      let ele = secondProperties[i];
                                      sqlInsertSecondProperty += `('${ele.function }', '${ele.property_name }',${dicControlPropertyID[dicParent[i]] }, ${info.insertId }, '${ele.unit}','${ele.range}', '${ele.value_description}' ),`;
                                  }
                                  sqlInsertSecondProperty = sqlInsertSecondProperty.substr(0,sqlInsertSecondProperty.length-1);
                                  trans.query(sqlInsertSecondProperty, function(err,insertSecondPropertyResult) {
                                      if(err || insertSecondPropertyResult.affectedRows !== secondProperties.length){
                                          trans.rollback();
                                          ctx.body = {
                                              result: 206,
                                              message: "新增设备失败"+ err.toString()
                                          };
                                          resolve(ctx);
                                      } else{
                                          trans.commit();
                                          ctx.body = {
                                              result: 200,
                                              id: info.insertId,
                                              message: "新增设备成功"
                                          };
                                          resolve(ctx);
                                      }
                                  })
                              }
                          }
                      });
                  }
              });
              trans.execute();
          }catch (e) {
              ctx.body = {
                  result: 205,
                  message: "错误"+ e.toString()
              };
              resolve(ctx);
          }
      });
  }catch (e) {
      ctx.body = {
          result: 205,
          message: "错误"+ e.toString()
      };
  }
}


exports.getList = async(ctx) => {
  try {
      let params = ctx.query;
      let counts = params.counts || 10;
      let indexfrom = params.indexfrom || 0;
      let keyword = params.keyword ? params.keyword.trim() : '';
      let vendor_id = params.vendor_id ? params.vendor_id : 0;
      let model_type_id = params.model_type_id ? params.model_type_id : 0;
      let sqlSelect = `SELECT * FROM v_product_detail `;
      let sqlWhere = `WHERE is_deleted = 0 `;
      if (keyword !== '' || parseInt(vendor_id) > 0 || parseInt(model_type_id) > 0) {
          if (keyword !== ''){
              sqlWhere += `and product_name like '%${keyword}%' or model_name like '%${keyword}%' `;
          }
          if (parseInt(vendor_id) > 0){
              sqlWhere +=  `and vendor_id = ${vendor_id} `;
          }
          if (parseInt(model_type_id) > 0) {
              sqlWhere += `and model_type_id = ${model_type_id} ` ;
          }
      }
      sqlSelect += sqlWhere;
      sqlSelect += ` ORDER BY product_id DESC LIMIT ${indexfrom}, ${counts} `;
      let selectProducts = await mysql.query(sqlSelect);
      for (let product of Object.values(selectProducts)){
          let protocol_id = parseInt(product.protocol_id);
          product.protocol_name = (protocol_id >= 1 && protocol_id <= 5) ? netMode[protocol_id-1].name : '未知';
          product.product_property = await mysql.query(`select function,property_name,unit,\`range\`, value_description
           from product_property where product_id = ${product.product_id} and parent_property_id is not null order by property_id`);

      } 
      totalResult = await mysql.query(`SELECT COUNT(product_id) AS total from v_product_detail ` + sqlWhere);
      ctx.body = {
          result: 200,
          list:selectProducts,
          totalpage:Math.ceil((totalResult.length > 0 ? totalResult[0].total : 0)/counts),
          totalcounts:totalResult.length > 0 ? totalResult[0].total : 0,
          message: "查询成功"
      };
  }catch (e) {
      ctx.body = {
          result: 205,
          message: "查询失败"+e.toString()
      };
  }
}

exports.update = async(ctx) => {
    try {
        let product_id = ctx.request.body.product_id || 0;
        let product_name = ctx.request.body.product_name ? ctx.request.body.product_name.trim() : '' || '';
        let pic_url = ctx.request.body.pic_url || '';
        let vendor_id = ctx.request.body.vendor_id || 0;
        let model_type_id = ctx.request.body.model_type_id || 0;
        let protocol_id = ctx.request.body.protocol_id || 0;
        let model_name = ctx.request.body.model_name || '';
        let product_property = ctx.request.body.product_property ?
            (ctx.request.body.product_property.trim() !== '' ? JSON.parse(ctx.request.body.product_property) : [])
            : [];
        if (parseInt(product_id) <= 0){
            ctx.body = {
                result: 201,
                message: `无效的product_id`
            };
            return;
        }
        if (product_name === '' || pic_url === '' || parseInt(vendor_id) <= 0 || parseInt(model_type_id) <= 0
            || parseInt(protocol_id) <= 0 || model_name === '') {
            ctx.body = {
                result: 202,
                message: `请补全设备属性`
            };
            return;
        }
        let selectProduct = await mysql.query(`select * from product where product_name = ? and vendor_id = ? and product_id <> ? and is_deleted = 0 `, [product_name,vendor_id,product_id]);
        if (selectProduct.length > 0 ){
            ctx.body = {
                result: 201,
                message: "已存在此产品"
            };
            return
        }
        let model_type_name = '未知';
        let selectRows = await mysql.query(`SELECT * FROM model_type WHERE model_type_id = ?`, model_type_id);
        if (selectRows.length > 0 && selectRows[0].model_type_name.length > 1){
            model_type_name = selectRows[0].model_type_name.substr(0,selectRows[0].model_type_name.length-1);
        }
        let firstProperties = [];
        let secondProperties = [];
        let dicControlId = {};
        let dicParent = {};
        let cotrolPropertylength = 0;
        for(let property of Object.values(product_property)){
            let match = property.property_name.match('_\\d+$');
            if (match && match.length > 0){
                if (!dicControlId[match[0]]) {
                    let newProperty = {};
                    newProperty.function = model_type_name + match[0].substr(1);
                    newProperty.property_name = 'control'+ match[0];
                    newProperty.unit = '';
                    newProperty.range = '';
                    newProperty.value_description = '';
                    firstProperties.push(newProperty);
                    dicControlId[match[0]] = firstProperties.length;
                }
                secondProperties.push(property);
                dicParent[cotrolPropertylength++] = dicControlId[match[0]] - 1;
            }else{
                if (!dicControlId['_0'])  {
                    let newProperty = {};
                    newProperty.function = product_name;
                    newProperty.property_name = 'control_0';
                    newProperty.unit = '';
                    newProperty.range = '';
                    newProperty.value_description = '';
                    firstProperties.push(newProperty);
                    dicControlId['_0'] = firstProperties.length;
                }
                secondProperties.push(property);
                dicParent[cotrolPropertylength++] = dicControlId['_0'] - 1;
            }
        }

        let control_type = (cotrolPropertylength > 0) ? 1 : 0;
        let update_time = moment().format('YYYY-MM-DD HH:mm:ss');
        let newproduct = {
            product_name,
            pic_url,
            vendor_id,
            model_type_id,
            protocol_id,
            model_name,
            control_type,
            update_time
        };
        await new Promise((resolve, reject) => {
            try {
                var trans = mysql.Client.startTransaction();
                trans.query(`delete from product_property WHERE product_id = ? `, product_id, function(err, deleteResult){
                    if(err){
                        trans.rollback();
                        ctx.body = {
                            result: 203,
                            message: "更新设备失败"+ err.toString()
                        };
                        resolve(ctx);
                    } else{
                        trans.query(`UPDATE product SET ? WHERE product_id = ? `, [newproduct,product_id], function(err, info) {
                            if(err || info.affectedRows === 0){
                                trans.rollback();
                                ctx.body = {
                                    result: 203,
                                    message: "更新设备失败"+ err.toString()
                                };
                                resolve(ctx);
                            }else{
                                if (firstProperties.length <= 0){
                                    trans.commit();
                                    ctx.body = {
                                        result: 200,
                                        id: product_id,
                                        message: "更新设备成功"
                                    };
                                    resolve(ctx);
                                    return;
                                }
                                let sqlInsertFirstProperty = `INSERT INTO product_property (function, property_name, product_id, unit, \`range\`, value_description) VALUES `;
                                firstProperties.forEach(ele => {
                                    sqlInsertFirstProperty += `('${ele.function}', '${ele.property_name}', ${product_id}, '${ele.unit}', '${ele.range}', '${ele.value_description}'),`;
                                })
                                sqlInsertFirstProperty = sqlInsertFirstProperty.substr(0,sqlInsertFirstProperty.length-1);
                                trans.query(sqlInsertFirstProperty, function(err,insertFirstPropertyResult) {
                                    if(err || insertFirstPropertyResult.affectedRows !== firstProperties.length){
                                        trans.rollback();
                                        ctx.body = {
                                            result: 204,
                                            message: "更新设备失败"+ err.toString()
                                        };
                                        resolve(ctx);
                                    } else{
                                        if (cotrolPropertylength <= 0){
                                            trans.commit();
                                            ctx.body = {
                                                result: 200,
                                                id: product_id,
                                                message: "更新设备成功"
                                            };
                                            resolve(ctx);
                                        } else{
                                            let dicControlPropertyID = {};
                                            for (i = 0; i < cotrolPropertylength; i++){
                                                dicControlPropertyID[i] = insertFirstPropertyResult.insertId + i;
                                            }
                                            let sqlInsertSecondProperty = `INSERT INTO product_property (function, property_name, parent_property_id, product_id, unit, \`range\`, value_description) VALUES `;
                                            for (i = 0;i < secondProperties.length; i++){
                                                let ele = secondProperties[i];
                                                sqlInsertSecondProperty += `('${ele.function }', '${ele.property_name }',${dicControlPropertyID[dicParent[i]] }, ${product_id}, '${ele.unit}','${ele.range}', '${ele.value_description}' ),`;
                                            }
                                            sqlInsertSecondProperty = sqlInsertSecondProperty.substr(0,sqlInsertSecondProperty.length-1);
                                            trans.query(sqlInsertSecondProperty, function(err,insertSecondPropertyResult) {
                                                if(err || insertSecondPropertyResult.affectedRows !== secondProperties.length){
                                                    trans.rollback();
                                                    ctx.body = {
                                                        result: 206,
                                                        message: "更新设备失败"+ err.toString()
                                                    };
                                                    resolve(ctx);
                                                } else{
                                                    trans.commit();
                                                    ctx.body = {
                                                        result: 200,
                                                        id: product_id,
                                                        message: "更新设备成功"
                                                    };
                                                    resolve(ctx);
                                                }
                                            })
                                        }
                                    }
                                });
                            }
                        });
                    }
                });
                trans.execute();
            }catch (e) {
                ctx.body = {
                    result: 205,
                    message: "错误"+ e.toString()
                };
                resolve(ctx);
            }
        });
    }catch (e) {
        ctx.body = {
            result: 205,
            message: "错误"+ e.toString()
        };
    }
}

exports.delete = async(ctx) => {
  let product_id = ctx.params.product_id || 0;

  try {
      if (parseInt(product_id) <= 0){
          ctx.body = {
              result: 201,
              message: "无效的product_id"
          };
          return
      }
      let existProducts = await mysql.query(`SELECT * FROM product WHERE product_id = ? and is_deleted = 0 `, product_id);
      if (existProducts.length <= 0){
          ctx.body = {
              result: 202,
              message: "对象不存在或已删除"
          };
      }else{
          existProducts[0].is_deleted = 1;
          existProducts[0].update_time = moment().format('YYYY-MM-DD HH:mm:ss');
          let ret = await mysql.query(`update product set ? WHERE product_id = ? `, [existProducts[0],product_id]);
          if (ret.affectedRows <= 0){
              ctx.body = {
                  result: 203,
                  message: "删除失败"
              };
          } else{
              ctx.body = {
                  result: 200,
                  message: "删除成功"
              };
          }
      }
  }catch (e) {
      ctx.body = {
          result: 205,
          message: "错误"+e.toString()
      };
  }
}

exports.getProperties = async(ctx) => {
    let product_id = ctx.query.product_id || 0;
    let need_detail = (ctx.query.need_detail && ctx.query.need_detail > 0 ) ? ctx.query.need_detail : 0 ;

    try {
        if (parseInt(product_id) <= 0){
            let v_device_id = ctx.query.v_device_id || 0;
            if (parseInt(v_device_id) <= 0){
                ctx.body = {
                    result: 201,
                    message: "无效的product_id"
                };
                return;
            } else{
                let selectRoomDevices = await mysql.query(`select * from t_room_v_device where v_device_id = ? `,v_device_id);
                if (selectRoomDevices.length <= 0 || !selectRoomDevices[0].product_id){
                    ctx.body = {
                        result: 201,
                        message: "product已删除"
                    };
                    return;
                }
                product_id = selectRoomDevices[0].product_id;
            }
        }
        let selectFirstProperties = await mysql.query(`SELECT property_id,function,property_name from product_property WHERE product_id = ? and parent_property_id is null `,product_id);
        if (need_detail > 0){
            for (let firstProperty of Object.values(selectFirstProperties)){
                firstProperty.subProperties = await mysql.query(`SELECT property_id,parent_property_id,function,property_name,unit,\`range\`,value_description from product_property WHERE product_id = ? and parent_property_id = ? `,[product_id,firstProperty.property_id]);
                for (let sonProperty of Object.values(firstProperty.subProperties)) {
                    if (sonProperty.value_description.startsWith('枚举值')) {
                        sonProperty.value_enum = [];
                        var patt1=new RegExp(/\d+（\S+）/,"g");
                        do
                        {
                            match_result=patt1.exec(sonProperty.value_description);
                            if (match_result && match_result.length > 0) {
                                let value_enum_one = {};
                                value_enum_one.value = parseInt(match_result[0].match(/\d+/)[0]);
                                let str = match_result[0].match(/（\S+）/)[0];
                                value_enum_one.description = str.substr(1,str.length-2);
                                sonProperty.value_enum.push(value_enum_one);
                            }
                        }
                        while (match_result!=null)
                    }
                    delete sonProperty.value_description;
                }
            }
        }
        ctx.body = {
            result: 200,
            list:selectFirstProperties,
            message: "查询成功"
        };
    }catch (e) {
        ctx.body = {
            result: 205,
            message: "查询失败"+e.toString()
        };
    }
}

